package com.sunny.cloudconfigclient.loader;

import org.springframework.boot.json.JsonParser;
import org.springframework.boot.json.JsonParserFactory;
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * PropertySourceLocator是springboot提供的一个属性文件的扩展接口(springboot启动过程中会触发)
 *
 * @author Sunny
 * @date 2020/7/16
 */
public class JsonPropertySourceLocator implements PropertySourceLocator {

    private static final String DEFAULT_LOCATION = "classpath:customer.json";
    private final ResourceLoader resourceLoader = new DefaultResourceLoader(getClass().getClassLoader());


    @Override
    public PropertySource<?> locate(Environment environment) {
        CustomerPropertySource source = new CustomerPropertySource("jsonPropertyConfig", mapPropertySource());
        return source;
    }

    private Map<String, Object> mapPropertySource() {
        //TODO 可以在这里访问远程配置中心获取配置 HTTP

        Resource resource = this.resourceLoader.getResource(DEFAULT_LOCATION);
        if (resource == null) {
            return null;
        }

        Map<String, Object> result = new HashMap<>();
        JsonParser jsonParser = JsonParserFactory.getJsonParser();
        Map<String, Object> fileMap = jsonParser.parseMap(readFile(resource));

        processMap("", result, fileMap);
        return result;
    }

    private void processMap(String prefix, Map<String, Object> result, Map<String, Object> fileMap) {
        if (prefix.length() > 0) {
            prefix += ".";
        }
        String finalPrefix = prefix;
        fileMap.forEach((k, v) -> {
            if (v instanceof Map) {
                processMap(finalPrefix + k, result, (Map<String, Object>) v);
            } else {
                result.put(finalPrefix + k, v);
            }
        });
    }

    /**
     * JSON格式
     * {
     *     {
     *         {
     *
     *         }
     *     }
     * }
     *
     * @param resource
     * @author Sunny
     * @date 2020/7/16
     */
    private String readFile(Resource resource) {
        FileInputStream fileInputStream = null;

        try {
            fileInputStream = new FileInputStream(resource.getFile());
            byte[] bytes = new byte[(int) resource.getFile().length()]; //错误演示
            fileInputStream.read(bytes);
            return new String(bytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
